<script setup>
import { computed, ref, watch } from 'vue'
import { PlusOutlined } from '@ant-design/icons-vue'
import { serverHost } from '@/request/index.js'
import { message } from 'ant-design-vue'

function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.readAsDataURL(file)
    reader.onload = () => resolve(reader.result)
    reader.onerror = (error) => reject(error)
  })
}
const emits = defineEmits(['update:modelValue'])
const props = defineProps({
  modelValue: { type: String, default: '' },
  // 最大上传文件数
  limit: { type: Number, default: 3 }
})

const previewVisible = ref(false)
const previewImage = ref('')
const previewTitle = ref('')
const fileList = ref([])
watch(
  () => props.modelValue,
  (val) => {
    if (val && fileList.value.length === 0) {
      fileList.value = val.split(',').map((item, i) => ({
        uid: i,
        name: 'image-' + i + '.png',
        status: 'done',
        response: {
          data: {
            url: item
          }
        },
        url: item
      }))
    }
  },
  { immediate: true }
)
// 取消
const handleCancel = () => {
  previewVisible.value = false
  previewTitle.value = ''
}
// 图片预览
const handlePreview = async (file) => {
  if (!file.url && !file.preview) {
    file.preview = await getBase64(file.originFileObj)
  }
  previewImage.value = file.url || file.preview
  previewVisible.value = true
  previewTitle.value = file.name || file.url.substring(file.url.lastIndexOf('/') + 1)
}
// 文件上传接口地址
const action = serverHost + '/file/common/upload'
// 请求头
const headers = {
  Authorization: 'Bearer ' + localStorage.getItem('token')
}

const result = computed(() => {
  return fileList.value
    .filter((item) => item.status === 'done')
    .map((item) => item.response.data.url)
})

watch(
  () => result.value,
  (newVal, oldVal) => {
    const oldValStr = JSON.stringify(oldVal || '[]')
    const newValStr = JSON.stringify(newVal || '[]')
    if (oldValStr !== newValStr) {
      let res = newVal.join(',')
      emits('update:modelValue', res)
    }
  },
  { deep: true, immediate: true }
)

const maxSize = 200
const beforeUpload = (file) => {
  if (
    file?.type === 'image/jpeg' ||
    file?.type === 'image/png' ||
    file?.type === 'video/mp4' ||
    file?.type === 'image/jpg'
  ) {
    if (file.size > maxSize * 1024 * 1024) {
      message.warning(`请上传${maxSize}M以内的文件`)
      return false
    }
    return true
  } else {
    message.warning(`上传格式只支持JPG/JPEG/PNG/MP4`)
    return Promise.reject()
  }
}

const change = ({ file }) => {
  if (
    file?.type === 'image/jpeg' ||
    file?.type === 'image/png' ||
    file?.type === 'video/mp4' ||
    file?.type === 'image/jpg'
  ) {
    if (file.size > maxSize * 1024 * 1024) {
      fileList.value.pop()
    }
  } else {
    fileList.value.pop()
  }
}
</script>

<template>
  <div class="clearfix">
    <a-upload
      v-model:file-list="fileList"
      :headers="headers"
      :action="action"
      list-type="picture-card"
      @preview="handlePreview"
      :beforeUpload="beforeUpload"
      @change="change"
    >
      <div v-if="fileList.length < props.limit">
        <PlusOutlined />
        <div style="margin-top: 8px">上传</div>
      </div>
    </a-upload>
    <a-modal :open="previewVisible" :title="previewTitle" :footer="null" @cancel="handleCancel">
      <img alt="example" style="width: 100%" :src="previewImage" />
    </a-modal>
  </div>
</template>

<style scoped>
/* you can make up upload button and sample style by using stylesheets */
.ant-upload-select-picture-card i {
  font-size: 32px;
  color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
  margin-top: 8px;
  color: #666;
}
</style>